home *** CD-ROM | disk | FTP | other *** search
- /*
- File: QuickSort.cp
-
- Contains: fastQSort() is a replacement for qsort(). Compared with the Think C library
- version of qsort, fastQSort is about 3 times faster (it takes 1/3 the time),
- and its speed isn't dependent on the data being sorted.
-
- One problem with qsort is that when the data is not in random order -- for
- example when it's already ordered, in reverse order, or almost sorted -- then
- qsort exhibits worst case behavior of N*N/2 operations. For N=1024 this can
- take about 30 seconds, instead of the usual 0.8 seconds. The fastQSort
- algorithm doesn't have this problem, because it randomly selects the pivot
- element, and so for N=1024 it requires about 0.26 secs +/- 0.02 secs.
-
- Also, because fastQSort doesn't exhibit worst case behavior, it doesn't
- require as much stack space, even though it has 12 bytes more of local
- variables.
-
- The things that make fastQSort so much faster than qsort are:
-
- 1) fastQSort picks the pivot element randomly, so it doesn't display worst
- case behavior.
-
- 2) fastQSort uses pointers and pointer arithmetic, avoiding multiplication
- whenever possible.
-
- 3) qsort uses std_swap() to swap the data between two locations, and
- std_swap loops through the data 3 times to perform the exchange! In
- comparison, swapMem() loops through the data just once.
-
- 4) fastQSort uses register variables whenever it makes good sense to do so.
-
- This version works within the shell of SortPicts.
-
-
-
- Written by: Haydn Huntley
- modified by Randy Thelen
-
- Copyright: Copyright © 1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 7/27/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1
-
-
- */
- #include "SortPicts.h"
-
- void QSort( SortPicts *sortPicts)
- {
- sortPicts->QSort();
- }
-
-
- void SortPicts::QSort( void)
- {
- QuickSortEngine( 0, N);
- }
-
-
- void SortPicts::ChooseMedian( long a, long b, long c)
- {
- long m; // median
-
- if( sortData[a] > sortData[b])
- if( sortData[a] > sortData[c])
- if( sortData[b] > sortData[c])
- m = b;
- else
- m = c;
- else
- m = a;
- else
- if( sortData[a] > sortData[c])
- m = a;
- else
- if( sortData[b] > sortData[c])
- m = c;
- else
- m = b;
-
- if( a != m)
- ExchangeSortItem( a, m);
- }
-
-
- void SortPicts::QuickSortEngine( long left, long right)
- {
- long n;
- long i, j;
-
- while( (n = right - left) > 1)
- {
- if( n < kPivotCutoff) // Use a random pivot
- ExchangeSortItem( left + Random( n), left);
- else
- ChooseMedian( left, left + (n >> 1),
- left + Random( n));
-
- i = left;
- j = right;
-
- while( 1)
- {
- i++;
- while( (i < right) && (sortData[i] < sortData[left]))
- i++;
-
- j--;
- while( (j > left) && (sortData[j] > sortData[left]))
- j--;
-
- if( i >= j)
- break;
-
- ExchangeSortItem( i, j);
- }
-
- if( j == left)
- {
- left++;
- continue;
- }
-
- ExchangeSortItem( left, j);
- if( (j - left) < (right - (j + 1)))
- {
- /* equivalent to doFastQSort (j + qSize, last); */
- /* to save stack space */
- QuickSortEngine( left, j);
- left = j + 1;
- }
- else
- {
- /* equivalent to doFastQSort (first, j); */
- /* to save stack space */
- QuickSortEngine( j+1, right);
- right = j;
- }
-
- }
- }
-
-